// 全局错误处理服务
import { ApiClientError } from './apiError'
import { useUIStore } from '@/stores/uiStore'

// 错误类型枚举
export enum ErrorType {
    NETWORK_ERROR = 'network_error',
    IMAGE_LOAD_ERROR = 'image_load_error',
    VIEWER_ERROR = 'viewer_error',
    VALIDATION_ERROR = 'validation_error',
    PERMISSION_ERROR = 'permission_error',
    TIMEOUT_ERROR = 'timeout_error',
    UNKNOWN_ERROR = 'unknown_error'
}

// 错误严重程度
export enum ErrorSeverity {
    LOW = 'low',
    MEDIUM = 'medium',
    HIGH = 'high',
    CRITICAL = 'critical'
}

// 错误详情接口
export interface ErrorDetails {
    type: ErrorType
    severity: ErrorSeverity
    message: string
    code?: string
    stack?: string
    context?: Record<string, unknown>
    timestamp: number
    userId?: string
    sessionId?: string
    userAgent?: string
    url?: string
}

// 错误处理选项
export interface ErrorHandlingOptions {
    showNotification?: boolean
    logToConsole?: boolean
    reportToService?: boolean
    retryable?: boolean
    maxRetries?: number
    fallbackAction?: () => void
}

// 错误处理器类
export class ErrorHandler {
    private static instance: ErrorHandler
    private errorQueue: ErrorDetails[] = []
    private maxQueueSize = 100
    private reportingEndpoint?: string

    private constructor() {
        this.setupGlobalErrorHandlers()
    }

    public static getInstance(): ErrorHandler {
        if (!ErrorHandler.instance) {
            ErrorHandler.instance = new ErrorHandler()
        }
        return ErrorHandler.instance
    }

    // 设置全局错误处理器
    private setupGlobalErrorHandlers(): void {
        // 处理未捕获的JavaScript错误
        if (typeof window !== 'undefined') {
            window.addEventListener('error', (event) => {
                this.handleError(new Error(event.message), {
                    type: ErrorType.UNKNOWN_ERROR,
                    severity: ErrorSeverity.HIGH,
                    context: {
                        filename: event.filename,
                        lineno: event.lineno,
                        colno: event.colno
                    }
                })
            })

            // 处理未捕获的Promise拒绝
            window.addEventListener('unhandledrejection', (event) => {
                this.handleError(event.reason, {
                    type: ErrorType.UNKNOWN_ERROR,
                    severity: ErrorSeverity.HIGH,
                    context: {
                        promise: 'unhandled_rejection'
                    }
                })
            })
        }
    }

    // 主要错误处理方法
    public handleError(
        error: Error | unknown,
        options: Partial<ErrorDetails> & ErrorHandlingOptions = {}
    ): void {
        const errorDetails = this.createErrorDetails(error, options)

        // 添加到错误队列
        this.addToQueue(errorDetails)

        // 根据选项执行不同的处理
        if (options.logToConsole !== false) {
            this.logError(errorDetails)
        }

        if (options.showNotification !== false) {
            this.showErrorNotification(errorDetails)
        }

        if (options.reportToService) {
            this.reportError(errorDetails)
        }

        // 执行回退操作
        if (options.fallbackAction) {
            try {
                options.fallbackAction()
            } catch (fallbackError) {
                console.error('Fallback action failed:', fallbackError)
            }
        }
    }

    // 创建错误详情对象
    private createErrorDetails(
        error: Error | unknown,
        options: Partial<ErrorDetails> = {}
    ): ErrorDetails {
        let message = '未知错误'
        let code: string | undefined
        let stack: string | undefined
        let type = ErrorType.UNKNOWN_ERROR

        if (error instanceof ApiClientError) {
            message = error.message
            code = error.code
            stack = error.stack
            type = this.mapApiErrorToType(error)
        } else if (error instanceof Error) {
            message = error.message
            stack = error.stack
            type = this.mapErrorToType(error)
        } else if (typeof error === 'string') {
            message = error
        } else if (error && typeof error === 'object') {
            message = JSON.stringify(error)
        }

        return {
            type: options.type || type,
            severity: options.severity || ErrorSeverity.MEDIUM,
            message: options.message || message,
            code: options.code || code,
            stack: options.stack || stack,
            context: options.context || {},
            timestamp: Date.now(),
            userId: this.getCurrentUserId(),
            sessionId: this.getSessionId(),
            userAgent: typeof window !== 'undefined' ? window.navigator.userAgent : undefined,
            url: typeof window !== 'undefined' ? window.location.href : undefined
        }
    }

    // 映射API错误到错误类型
    private mapApiErrorToType(error: ApiClientError): ErrorType {
        if (error.status) {
            if (error.status >= 400 && error.status < 500) {
                if (error.status === 401 || error.status === 403) {
                    return ErrorType.PERMISSION_ERROR
                }
                return ErrorType.VALIDATION_ERROR
            }
            if (error.status >= 500) {
                return ErrorType.NETWORK_ERROR
            }
        }
        return ErrorType.UNKNOWN_ERROR
    }

    // 映射通用错误到错误类型
    private mapErrorToType(error: Error): ErrorType {
        const message = error.message.toLowerCase()

        if (message.includes('network') || message.includes('fetch')) {
            return ErrorType.NETWORK_ERROR
        }
        if (message.includes('timeout')) {
            return ErrorType.TIMEOUT_ERROR
        }
        if (message.includes('permission') || message.includes('unauthorized')) {
            return ErrorType.PERMISSION_ERROR
        }
        if (message.includes('image') || message.includes('dicom')) {
            return ErrorType.IMAGE_LOAD_ERROR
        }
        if (message.includes('viewer') || message.includes('canvas')) {
            return ErrorType.VIEWER_ERROR
        }

        return ErrorType.UNKNOWN_ERROR
    }

    // 添加错误到队列
    private addToQueue(errorDetails: ErrorDetails): void {
        this.errorQueue.push(errorDetails)

        // 保持队列大小限制
        if (this.errorQueue.length > this.maxQueueSize) {
            this.errorQueue.shift()
        }
    }

    // 控制台日志记录
    private logError(errorDetails: ErrorDetails): void {
        const logLevel = this.getLogLevel(errorDetails.severity)
        const logMessage = `[${errorDetails.type}] ${errorDetails.message}`

        console.group(`🚨 Error Handler - ${errorDetails.severity.toUpperCase()}`)
        console[logLevel](logMessage)

        if (errorDetails.code) {
            console.log('Error Code:', errorDetails.code)
        }

        if (errorDetails.context && Object.keys(errorDetails.context).length > 0) {
            console.log('Context:', errorDetails.context)
        }

        if (errorDetails.stack) {
            console.log('Stack Trace:', errorDetails.stack)
        }

        console.groupEnd()
    }

    // 获取日志级别
    private getLogLevel(severity: ErrorSeverity): 'log' | 'warn' | 'error' {
        switch (severity) {
            case ErrorSeverity.LOW:
                return 'log'
            case ErrorSeverity.MEDIUM:
                return 'warn'
            case ErrorSeverity.HIGH:
            case ErrorSeverity.CRITICAL:
                return 'error'
            default:
                return 'error'
        }
    }

    // 显示错误通知
    private showErrorNotification(errorDetails: ErrorDetails): void {
        if (typeof window === 'undefined') return

        try {
            const { addNotification } = useUIStore.getState()

            const notificationType = this.mapSeverityToNotificationType(errorDetails.severity)
            const title = this.getErrorTitle(errorDetails.type)
            const message = this.getUserFriendlyMessage(errorDetails)

            addNotification({
                type: notificationType,
                title,
                message,
                duration: this.getNotificationDuration(errorDetails.severity)
            })
        } catch (notificationError) {
            console.error('Failed to show error notification:', notificationError)
        }
    }

    // 映射严重程度到通知类型
    private mapSeverityToNotificationType(severity: ErrorSeverity): 'error' | 'warning' | 'info' {
        switch (severity) {
            case ErrorSeverity.LOW:
                return 'info'
            case ErrorSeverity.MEDIUM:
                return 'warning'
            case ErrorSeverity.HIGH:
            case ErrorSeverity.CRITICAL:
                return 'error'
            default:
                return 'error'
        }
    }

    // 获取错误标题
    private getErrorTitle(type: ErrorType): string {
        const titles: Record<ErrorType, string> = {
            [ErrorType.NETWORK_ERROR]: '网络错误',
            [ErrorType.IMAGE_LOAD_ERROR]: '影像加载错误',
            [ErrorType.VIEWER_ERROR]: '查看器错误',
            [ErrorType.VALIDATION_ERROR]: '验证错误',
            [ErrorType.PERMISSION_ERROR]: '权限错误',
            [ErrorType.TIMEOUT_ERROR]: '请求超时',
            [ErrorType.UNKNOWN_ERROR]: '系统错误'
        }
        return titles[type] || '未知错误'
    }

    // 获取用户友好的错误消息
    private getUserFriendlyMessage(errorDetails: ErrorDetails): string {
        const friendlyMessages: Record<ErrorType, string> = {
            [ErrorType.NETWORK_ERROR]: '网络连接出现问题，请检查网络连接后重试',
            [ErrorType.IMAGE_LOAD_ERROR]: '影像文件加载失败，请检查文件格式或重新上传',
            [ErrorType.VIEWER_ERROR]: '影像查看器出现问题，请刷新页面重试',
            [ErrorType.VALIDATION_ERROR]: '输入数据有误，请检查后重新提交',
            [ErrorType.PERMISSION_ERROR]: '您没有执行此操作的权限，请联系管理员',
            [ErrorType.TIMEOUT_ERROR]: '请求超时，请稍后重试',
            [ErrorType.UNKNOWN_ERROR]: '系统出现未知错误，请联系技术支持'
        }

        return friendlyMessages[errorDetails.type] || errorDetails.message
    }

    // 获取通知持续时间
    private getNotificationDuration(severity: ErrorSeverity): number {
        switch (severity) {
            case ErrorSeverity.LOW:
                return 3000
            case ErrorSeverity.MEDIUM:
                return 5000
            case ErrorSeverity.HIGH:
                return 8000
            case ErrorSeverity.CRITICAL:
                return 0 // 不自动消失
            default:
                return 5000
        }
    }

    // 报告错误到服务
    private async reportError(errorDetails: ErrorDetails): Promise<void> {
        if (!this.reportingEndpoint) return

        try {
            await fetch(this.reportingEndpoint, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(errorDetails)
            })
        } catch (reportingError) {
            console.error('Failed to report error:', reportingError)
        }
    }

    // 获取当前用户ID
    private getCurrentUserId(): string | undefined {
        // 这里可以从认证状态或本地存储获取用户ID
        return undefined
    }

    // 获取会话ID
    private getSessionId(): string {
        if (typeof window === 'undefined') return 'server'

        let sessionId = sessionStorage.getItem('sessionId')
        if (!sessionId) {
            sessionId = `session_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`
            sessionStorage.setItem('sessionId', sessionId)
        }
        return sessionId
    }

    // 设置错误报告端点
    public setReportingEndpoint(endpoint: string): void {
        this.reportingEndpoint = endpoint
    }

    // 获取错误统计
    public getErrorStats(): {
        total: number
        byType: Record<ErrorType, number>
        bySeverity: Record<ErrorSeverity, number>
        recent: ErrorDetails[]
    } {
        const byType: Record<ErrorType, number> = {} as Record<ErrorType, number>
        const bySeverity: Record<ErrorSeverity, number> = {} as Record<ErrorSeverity, number>

        this.errorQueue.forEach(error => {
            byType[error.type] = (byType[error.type] || 0) + 1
            bySeverity[error.severity] = (bySeverity[error.severity] || 0) + 1
        })

        return {
            total: this.errorQueue.length,
            byType,
            bySeverity,
            recent: this.errorQueue.slice(-10) // 最近10个错误
        }
    }

    // 清除错误队列
    public clearErrorQueue(): void {
        this.errorQueue = []
    }
}

// 导出单例实例
export const errorHandler = ErrorHandler.getInstance()

// 便捷的错误处理函数
export const handleError = (
    error: Error | unknown,
    options?: Partial<ErrorDetails> & ErrorHandlingOptions
) => {
    errorHandler.handleError(error, options)
}

// 特定类型的错误处理函数
export const handleNetworkError = (error: Error | unknown, context?: Record<string, unknown>) => {
    handleError(error, {
        type: ErrorType.NETWORK_ERROR,
        severity: ErrorSeverity.HIGH,
        context,
        retryable: true
    })
}

export const handleImageLoadError = (error: Error | unknown, context?: Record<string, unknown>) => {
    handleError(error, {
        type: ErrorType.IMAGE_LOAD_ERROR,
        severity: ErrorSeverity.MEDIUM,
        context
    })
}

export const handleViewerError = (error: Error | unknown, context?: Record<string, unknown>) => {
    handleError(error, {
        type: ErrorType.VIEWER_ERROR,
        severity: ErrorSeverity.HIGH,
        context
    })
}

export const handleValidationError = (error: Error | unknown, context?: Record<string, unknown>) => {
    handleError(error, {
        type: ErrorType.VALIDATION_ERROR,
        severity: ErrorSeverity.LOW,
        context,
        showNotification: true
    })
}

export const handlePermissionError = (error: Error | unknown, context?: Record<string, unknown>) => {
    handleError(error, {
        type: ErrorType.PERMISSION_ERROR,
        severity: ErrorSeverity.HIGH,
        context
    })
}